package qc.module.platform.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.platform.dto.messageConfig.MessageConfigDto;
import qc.module.platform.entity.QcMessageConfig;
import qc.module.platform.mapper.MessageConfigMapper;
import qc.module.platform.repository.QcMessageConfigRepository;

import java.util.List;
import java.util.Objects;

/**
 * 消息通知配置Service
 *
 * @author QuCheng Tech
 * @create 2023/11/03
 */
@Service
public class MessageConfigService {
    private QcMessageConfigRepository repository;
    private ProjectService projectService;

    @Autowired
    public void setRepository(QcMessageConfigRepository repository) {
        this.repository = repository;
    }

    @Autowired
    public void setProjectService(ProjectService projectService) {
        this.projectService = projectService;
    }

    /**
     * 查询平台消息通知配置
     *
     * @return 平台消息通知配置记录集合
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public List<MessageConfigDto> queryPlatform() {
        // 1.查询数据记录
        List<QcMessageConfig> enList = repository.selectList(new LambdaQueryWrapper<>());

        // 2.如果有数据记录，enList转换为dtoList返回
        if (enList.size() > 0x0)
            return MessageConfigMapper.MAPPER.toDtoList(enList);
        return null;
    }

    /**
     * 查询项目消息通知配置
     *
     * @param projectCode 项目编码
     * @return 项目消息通知配置记录集合
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public List<MessageConfigDto> queryProject(String projectCode) throws QCPromptException {
        // 1.查询条件判空，为空则提示
        if (StringUtils.isBlank(projectCode))
            throw new QCPromptException("项目编码不能为空");

        // 2.查询项目编码是否存在，不存在则提示
        if (!projectService.hasCodeExist(projectCode))
            throw new QCPromptException("项目编码不存在");

        // 3.构造查询条件
        LambdaQueryWrapper<QcMessageConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcMessageConfig::getProjectCode, projectCode);

        // 4.查询数据记录
        List<QcMessageConfig> enList = repository.selectList(wrapper);

        // 5.如果有数据记录，enList转换为dtoList返回
        if (enList.size() > 0x0)
            return MessageConfigMapper.MAPPER.toDtoList(enList);
        return null;
    }

    /**
     * 获取指定消息通知配置
     *
     * @param msgCode 消息代码
     * @return 指定消息通知配置记录
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public MessageConfigDto get(String msgCode) {
        // 1.获取指定消息代码的数据记录
        QcMessageConfig en = repository.selectById(msgCode);

        // 2.判断数据记录是否存在，存在则en转换为dto返回
        if (Objects.nonNull(en))
            return MessageConfigMapper.MAPPER.toDto(en);
        return null;
    }

    /**
     * 新增消息通知配置记录
     *
     * @param dto 新增内容dto
     * @return 返回null表示成功，其他表示错误或提示信息
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public String add(MessageConfigDto dto) {
        // 1.验证消息通知配置DTO
        String result = validMessageDto(dto);
        if (result != null) {
            return result;
        }

        // 2.判断消息代码是否已经存在，存在则提示
        if (hasMsgCodeExist(dto.getCode()))
            return QCUnifyReturnValue.Warn("消息代码已存在");

        // 3.dto转为entity
        QcMessageConfig en = MessageConfigMapper.MAPPER.addOrUpdateDtoToEntity(dto);

        // 4.保存数据记录
        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("保存失败");
        return QCUnifyReturnValue.Success();
    }


    /**
     * 修改消息通知配置记录
     *
     * @param dto 修改内容dto
     * @return 返回null表示成功，其他表示错误或提示信息
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public String update(MessageConfigDto dto) {
        // 1.验证消息通知配置DTO
        String result = validMessageDto(dto);
        if (result != null) {
            return result;
        }

        // 2.判断消息代码是否已经存在，不存在则提示
        if (!hasMsgCodeExist(dto.getCode()))
            return QCUnifyReturnValue.Warn("修改的消息代码不存在");

        // 3.dto转为entity
        QcMessageConfig en = MessageConfigMapper.MAPPER.addOrUpdateDtoToEntity(dto);

        // 4.更新数据记录
        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除指定消息通知配置记录
     * 物理删除
     *
     * @param msgCode 消息代码
     * @return 返回null表示成功，其他表示错误或提示信息
     * @author QcCheng Tech
     * @since 2023/11/03
     */
    public String delete(String msgCode) {
        // 1.判断删除的数据记录是否存在，不存在则提示
        QcMessageConfig en = repository.selectById(msgCode);
        if (Objects.isNull(en))
            return QCUnifyReturnValue.Warn("消息通知配置不存在");

        // 2.删除记录
        repository.deleteById(msgCode);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 验证消息通知配置DTO
     *
     * @param dto 消息通知配置DTO
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/6/26
     */
    public String validMessageDto(MessageConfigDto dto) {
        // 1.内容判空
        if (Objects.isNull(dto))
            return QCUnifyReturnValue.Warn("新增对象不能为空");
        if (StringUtils.isBlank(dto.getCode()))
            return QCUnifyReturnValue.Warn("消息代码不能为空");
        if (StringUtils.isBlank(dto.getName()))
            return QCUnifyReturnValue.Warn("消息名称不能为空");
        if (dto.getReceiverType() == 0x0)
            return QCUnifyReturnValue.Warn("请选择接收者类型");
        if (StringUtils.isBlank(dto.getContent()))
            return QCUnifyReturnValue.Warn("内容模板不能为空");
        if (dto.getLevel() == 0x0)
            return QCUnifyReturnValue.Warn("请选择重要等级");
        if (dto.getTimelyType() == 0x0)
            return QCUnifyReturnValue.Warn("请选择时效性类型");
        if (dto.getNoticeType() == 0x0)
            return QCUnifyReturnValue.Warn("请选择通知方式");

        // 2.如果有项目编码，查询项目编码是否存在，不存在则提示
        if (StringUtils.isNotBlank(dto.getProjectCode())) {
            if (!projectService.hasCodeExist(dto.getProjectCode()))
                return QCUnifyReturnValue.Warn("项目编码不存在");
        }

        // 3.判断消息名称是否已经存在，存在则提示
        if (hasNameExist(dto.getName(), dto.getCode()))
            return QCUnifyReturnValue.Warn("消息名称已经存在");

        return null;
    }

    /**
     * 判断指定的消息代码是否已经存在
     *
     * @param msgCode 消息代码
     * @return true表示已存在，false表示不存在
     * @author QuCheng Tech
     * @since 2023/11/6
     */
    boolean hasMsgCodeExist(String msgCode) {
        // 1.构造查询条件
        LambdaQueryWrapper<QcMessageConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcMessageConfig::getMsgCode, msgCode);

        // 2.查询指定消息代码数据记录，存在返回true，不存在返回false
        QcMessageConfig en = repository.selectOne(wrapper);
        if (Objects.nonNull(en))
            return true;
        return false;
    }

    /**
     * 检查消息名称是否已经存在
     *
     * @param name    消息名称
     * @param msgCode 消息代码
     * @return true表示名称已存在，false表示名称不存在
     * @author QuCheng Tech
     * @since 2023/11/6
     */
    boolean hasNameExist(String name, String msgCode) {
        // 1.构造查询条件，验证名称是否重复条件：name=name and code<>code
        LambdaQueryWrapper<QcMessageConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcMessageConfig::getName, name);
        wrapper.ne(QcMessageConfig::getMsgCode, msgCode);

        // 2.查询记录
        QcMessageConfig en = repository.selectOne(wrapper);
        if (en != null)
            return true;
        return false;
    }
}
